-module(cdr_to_json).
-include("subscriber.hrl").
-include("cdr.hrl").
-include("network.hrl").
-export([do/1,record_to_json/1]).

do(Sub) ->
	rfc4627:encode(record_to_json(Sub)).

record_to_json(Sub) when is_record(Sub,subscriber) ->
	case Sub#subscriber.type of
	wlan ->
		record_to_json(wlan,Sub);
	_ ->
		{obj,
		[{"result","unknow"}]
		}
	end;
record_to_json(Cdr) when (is_record(Cdr,lte_s1_cdr)) and (Cdr#lte_s1_cdr.rrc_con_reason =:= tac)  ->
	{obj,
		[
		{"rrc_con_reason",list_to_binary(atom_to_list(Cdr#lte_s1_cdr.rrc_con_reason))},
		{"end_reason",term_to_string({end_reason,Cdr#lte_s1_cdr.end_reason})},
		{"start_time",term_to_string({date_time,Cdr#lte_s1_cdr.start_time})},
		{"end_time",term_to_string({date_time,Cdr#lte_s1_cdr.end_time})},
		{"user_id",term_to_string({user_id,Cdr#lte_s1_cdr.user_id})},
		{"end_mode",list_to_binary(atom_to_list(Cdr#lte_s1_cdr.end_mode))},
		{"aux_info",term_to_string({aux_info,Cdr#lte_s1_cdr.aux_info,""})}
		]
	};
record_to_json(Cdr) when (is_record(Cdr,lte_s1_cdr)) and (Cdr#lte_s1_cdr.rrc_con_reason =:= service_request)  ->
	{obj,
		[
		{"rrc_con_reason",list_to_binary(atom_to_list(Cdr#lte_s1_cdr.rrc_con_reason))},
		{"end_reason",term_to_string({end_reason,Cdr#lte_s1_cdr.end_reason})},
		{"start_time",term_to_string({date_time,Cdr#lte_s1_cdr.start_time})},
		{"end_time",term_to_string({date_time,Cdr#lte_s1_cdr.end_time})},
		{"user_id",term_to_string({user_id,Cdr#lte_s1_cdr.user_id})},
		{"end_mode",list_to_binary(atom_to_list(Cdr#lte_s1_cdr.end_mode))},
		{"aux_info",term_to_string({aux_info,Cdr#lte_s1_cdr.aux_info,""})},
		{"rab_info",term_to_string({rab_info,Cdr#lte_s1_cdr.rab_info,""})}
		]
	};
record_to_json(Cdr) when (is_record(Cdr,lte_s1_cdr)) and (Cdr#lte_s1_cdr.rrc_con_reason =:= auth_request)  ->
	{obj,
		[
		{"rrc_con_reason",list_to_binary(atom_to_list(Cdr#lte_s1_cdr.rrc_con_reason))},
		{"end_reason",term_to_string({end_reason,Cdr#lte_s1_cdr.end_reason})},
		{"start_time",term_to_string({date_time,Cdr#lte_s1_cdr.start_time})},
		{"end_time",term_to_string({date_time,Cdr#lte_s1_cdr.end_time})},
		{"user_id",term_to_string({user_id,Cdr#lte_s1_cdr.user_id})},
    {"access_info",term_to_string({access_info,Cdr#lte_s1_cdr.access_info})},
		{"end_mode",list_to_binary(atom_to_list(Cdr#lte_s1_cdr.end_mode))},
		{"aux_info",term_to_string({aux_info,Cdr#lte_s1_cdr.aux_info,""})},
		{"rab_info",term_to_string({rab_info,Cdr#lte_s1_cdr.rab_info,""})}
		]
	};
record_to_json(Cdr) when (is_record(Cdr,lte_s1_cdr)) and (Cdr#lte_s1_cdr.rrc_con_reason =:= attach_request)  ->
	{obj,
		[
		{"rrc_con_reason",list_to_binary(atom_to_list(Cdr#lte_s1_cdr.rrc_con_reason))},
		{"end_reason",term_to_string({end_reason,Cdr#lte_s1_cdr.end_reason})},
		{"start_time",term_to_string({date_time,Cdr#lte_s1_cdr.start_time})},
		{"end_time",term_to_string({date_time,Cdr#lte_s1_cdr.end_time})},
		{"user_id",term_to_string({user_id,Cdr#lte_s1_cdr.user_id})},
		{"end_mode",list_to_binary(atom_to_list(Cdr#lte_s1_cdr.end_mode))},
		{"aux_info",term_to_string({aux_info,Cdr#lte_s1_cdr.aux_info,""})},
		{"rab_info",term_to_string({rab_info,Cdr#lte_s1_cdr.rab_info,""})}
		]
	};
record_to_json(Cdr) when (is_record(Cdr,lte_s1_cdr)) ->
	{obj,[
		{"rrc_con_reason",list_to_binary(atom_to_list(Cdr#lte_s1_cdr.rrc_con_reason))}
		]
	};
record_to_json(Rec) when (is_record(Rec,sp_state)) ->
	{obj,
		[
		{"addr",term_to_string({ip,Rec#sp_state.address})},
		{"role",list_to_binary(atom_to_list(Rec#sp_state.type))},
		{"send",term_to_string(Rec#sp_state.send_sig_num)},
		{"recv",term_to_string(Rec#sp_state.recv_sig_num)},
		{"conflict",term_to_string(Rec#sp_state.conflict_num)}
		]
	};
record_to_json(Rec) ->
  {obj,[{"error",list_to_binary(io_lib:format("Unknow Record",[Rec]))}]}.
record_to_json(sub_wlan,Info) ->
	{obj,
		[
		 {"ap",term_to_string({ip,Info#sub_wlan.ap})},
		 {"ac",term_to_string({ip,Info#sub_wlan.ac})},
		 {"bssid",term_to_string({mac,Info#sub_wlan.bssid})}
		]
	};
record_to_json(wlan,Sub) ->
	{obj,[
		{"callingid",term_to_string({mac,Sub#subscriber.mac})},
		{"ip",term_to_string({ip,Sub#subscriber.ip})},
		{"end_reason",term_to_string({string,Sub#subscriber.end_reason})},
		{"up_packet_num",Sub#subscriber.total_p_up},
		{"down_packet_num",Sub#subscriber.total_p_down},
		{"ran_info",record_to_json(sub_wlan,Sub#subscriber.ran_info)}
		]
	}.
term_to_string(Integer) when is_integer(Integer) ->
	list_to_binary(io_lib:format("~B",[Integer]));
term_to_string({_,unknown}) ->
	<<"unknown">>;
term_to_string({mac,<<MAC1:8,MAC2:8,MAC3:8,MAC4:8,MAC5:8,MAC6:8>>}) ->
	list_to_binary(io_lib:format("~.16B:~.16B:~.16B:~.16B:~.16B:~.16B",[MAC1,MAC2,MAC3,MAC4,MAC5,MAC6]));

term_to_string({ip,{IP1,IP2,IP3,IP4}}) ->
	list_to_binary(io_lib:format("~B.~B.~B.~B",[IP1,IP2,IP3,IP4]));
term_to_string({ip,<<IP1:8,IP2:8,IP3:8,IP4:8>>}) ->
	list_to_binary(io_lib:format("~B.~B.~B.~B",[IP1,IP2,IP3,IP4]));
term_to_string({string,Str}) ->
	list_to_binary(Str);
term_to_string({date_time,{{{Year,Month,Day},{Hour,Min,Sec}},USec}}) ->
	list_to_binary(io_lib:format("~p-~p-~p ~p:~p:~p ~p",[Year + 1970,Month,Day,Hour,Min,Sec,USec]));
term_to_string({user_id,{tmsi,Tmsi}}) ->
	list_to_binary(io_lib:format("tmsi:~.16B",[Tmsi]));
term_to_string({user_id,{imsi,Imsi}}) ->
	list_to_binary(io_lib:format("tmsi:~p",[Imsi]));
term_to_string({user_id,{guti,Guti}}) ->
	list_to_binary(io_lib:format("guti:~p",[Guti]));
term_to_string({aux_info,[{message,Index}|Other],Cur_Str}) ->
	term_to_string({aux_info,Other,io_lib:format("~s msg:~p",[Cur_Str,Index])});
term_to_string({aux_info,[_Unknown|Other],Cur_Str}) ->
	term_to_string({aux_info,Other,Cur_Str});
term_to_string({aux_info,[],Cur_Str}) ->
	list_to_binary(Cur_Str);
term_to_string({rab_info,[{Rab_Id,{IP1,IP2,IP3,IP4},TeId}|Others],Cur_Str}) ->
	term_to_string({rab_info,Others,io_lib:format("~s rab:~p(~p.~p.~p.~p,~.16B)",[Cur_Str,Rab_Id,IP1,IP2,IP3,IP4,TeId])});
term_to_string({rab_info,[],Cur_Str}) ->
	list_to_binary(Cur_Str);
term_to_string({end_reason,Value}) when is_atom(Value) ->
  atom_to_list(Value);
term_to_string({end_reason,Value}) when is_atom(Value) ->
  list_to_binary(io_lib:format("~p",[Value]));
term_to_string({access_info,{MMe, ENodeB}}) ->
  IP1 = term_to_string({ip,MMe}),
  IP2 = term_to_string({ip,ENodeB}),
	<<IP1/binary,",",IP2/binary>>;
term_to_string(Unknown) ->
	list_to_binary(io_lib:format("uncoded ~p",[Unknown])).

